﻿using SCG.General;
using SCG.SolarVengeanceEngine;
using SCG.TurboSprite;
using SCG.WinForms;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SCG.SolarVengeance
{
    public class StarSystemSprite : Sprite
    {
        //constructor
        public StarSystemSprite(StarSystem system) 
            : base()
        {
            StarSystem = system;
            Shape = new Rectangle(-Constants.CellHalf, -Constants.CellHalf, Constants.CellSize, Constants.CellSize);
        }

        //the starsystem
        public StarSystem StarSystem { get; set; }

        //Dynamically adjust the visible bounds based on scanners
        public override void Process()
        {
            if (StarSystem.OwnedByCurrentPlayer && _scanners != StarSystem.Scanners)
            {
                _scanners = StarSystem.Scanners;
                int radius = StarSystem.Scanners * Constants.CellSize;
                Shape = new RectangleF(-radius, -radius, radius * 2 + Constants.CellSize, radius * 2 + Constants.CellSize);
                ClickShape = new RectangleF(0, 0, Constants.CellSize, Constants.CellSize);
            }
        }

        //render
        public override void Render(Graphics g)
        {
            int xDraw = (int)(X - Surface.OffsetX);
            int yDraw = (int)(Y - Surface.OffsetY);

            //see if we need to get a new bitmap
            if (_bmp == null || StarSystem.Color != _color || StarSystem.Value != _value || StarSystem.VisibleToCurrentPlayer != _wasVisible)
            {
                _color = StarSystem.Color;
                _value = StarSystem.Value;
                _wasVisible = StarSystem.VisibleToCurrentPlayer;

                //get the base image
                int idx = 0;
                if (StarSystem.VisibleToCurrentPlayer)
                {
                    idx = StarSystem.Value;
                    if (idx > 20)
                        idx = 20;
                    if (idx < 0)
                        idx = 0;
                }
                Bitmap baseImage = _baseImages[idx];

                //get colorized version
                _bmp = ImageColorizer.Colorize(baseImage, StarSystem.Color.ToColor(), Color.Black);
            }

            //draw image
            g.DrawImage(_bmp, xDraw - _bmp.Width / 2, yDraw - _bmp.Height / 2);

            //capital?
            if (StarSystem.VisibleToCurrentPlayer && StarSystem.IsCapital)
            {
                Bitmap colorized = ImageColorizer.Colorize(CapitalSymbol, StarSystem.Color.ToColor(), Color.Black);
                g.DrawImage(colorized, xDraw - colorized.Width / 2, yDraw - colorized.Height / 2);
            }

            //draw the shields
            if (StarSystem.VisibleToCurrentPlayer)
            {
                _shieldCounter++;
                int shld = StarSystem.Shields;
                int radius = 20;
                while (shld > 0)
                {
                    int idx = (shld + _shieldCounter) % 10;
                    if (shld >= 100)
                        ShieldPens[idx].Width = 8;
                    if (shld >= 25)
                        ShieldPens[idx].Width = 5;
                    g.DrawEllipse(ShieldPens[idx], xDraw - radius, yDraw - radius, radius * 2, radius * 2);
                    if (shld >= 100)
                    {
                        ShieldPens[idx].Width = 1;
                        shld -= 100;
                        radius += 10;
                    }
                    else if (shld >= 25)
                    {
                        ShieldPens[idx].Width = 1;
                        shld -= 25;
                        radius += 7;
                    }
                    else
                    {
                        shld--;
                        radius += 2;
                    }
                }
            }

            //draw the scanners
            if (StarSystem.OwnedByCurrentPlayer && StarSystem.Scanners > 1)
            {
                int radius = StarSystem.Scanners * Constants.CellSize + Constants.CellHalf;
                g.DrawEllipse(ScannerPen, xDraw - radius, yDraw - radius, radius * 2, radius * 2);
            }

            //draw the name
            int nameWidth = (int)g.MeasureString(StarSystem.Name, NameFont).Width;
            int nameX = (int)(X - nameWidth / 2);
            DrawLabel(g, StarSystem.Name, NameFont, Brushes.Silver, nameX - Surface.OffsetX, Y + Constants.CellHalf - Surface.OffsetY - 8); 
 
            //draw value/resources
            if (StarSystem.VisibleToCurrentPlayer)
            {
                DrawLabel(g, "V" + StarSystem.Value, ValuesFont, Brushes.Silver, xDraw - Constants.CellHalf - 5, yDraw - Constants.CellHalf);
                if (StarSystem.ResourcesInt != 0)
                    DrawLabel(g, "R" + StarSystem.ResourcesInt, ValuesFont, Brushes.Silver, xDraw + Constants.CellHalf - 20, yDraw - Constants.CellHalf);
            }
        }

        //private members
        private static Font ValuesFont = new Font("Arial", 7);
        private static Font NameFont = new Font("Arial", 8);
        private static Pen[] ShieldPens = new Pen[10];
        private static Brush LabelBackgroundBrush = new SolidBrush(Color.FromArgb(128, 0, 0, 0));
        private static Bitmap[] _baseImages = new Bitmap[21];
        private static Pen ScannerPen = new Pen(Color.FromArgb(96, Color.Cyan));
        private static Bitmap CapitalSymbol;
        private Bitmap _bmp = null;
        private int _value;
        private SCGColor _color;
        private int _scanners = -1;
        private byte _shieldCounter = 0;
        private bool _wasVisible;

        //static constructor
        static StarSystemSprite()
        {
            //load base starsystem images
            Bitmap baseImage = (Bitmap)Bitmap.FromFile("Images\\StarSystem.bmp");
            baseImage = ImageUtils.Create32bppBitmap(baseImage);
            CapitalSymbol = (Bitmap)Bitmap.FromFile("Images\\CapitalSymbol.bmp");

            //create versions in 21 sizes (Value 0 to 20+)
            int size = baseImage.Width;
            _baseImages[20] = baseImage;
            for (int idx = 19; idx >= 0; idx--)
            {
                size--;
                Bitmap resized = ImageUtils.ResizeBitmap(baseImage, size, size, true);
                _baseImages[idx] = resized;
            }

            //initialize shield color array
            byte green = 255;
            for (int i = 0; i < 10; i++)
            {
                ShieldPens[i] = new Pen(Color.FromArgb(128, 0, green, 0));
                green -= 20;
            }  
        }

        //Draw a label with a black background
        private void DrawLabel(Graphics g, string text, Font font, Brush brush, float x, float y)
        {
            SizeF size = g.MeasureString(text, font);
            int width = (int)size.Width;
            int height = (int)size.Height;
            g.FillRectangle(LabelBackgroundBrush, x, y, width, height);
            g.DrawString(text, font, brush, x, y);
        }
    }
}
